package jwt

import (
	"crypto/sha1"
	"encoding/hex"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/golang-jwt/jwt/v5"
	"github.com/redis/go-redis/v9"
	"github.com/spf13/viper"
	"go-admin/server/internal/domain"
	"log"
	"time"
)

type jwtHandler struct {
	cmd          redis.Cmdable
	rtExpiration time.Duration
}

func NewJwtHandler(cmd redis.Cmdable) Handler {
	return &jwtHandler{
		cmd:          cmd,
		rtExpiration: time.Hour * 24 * 7,
	}
}

func (j *jwtHandler) SetJwtTokenForAdmin(ctx *gin.Context, admin domain.Admin) (string, error) {
	sha1Hash := sha1.New()
	idBytes := []byte(fmt.Sprintf("%d", admin.AdminID))
	sha1Hash.Write(idBytes)
	hashed := sha1Hash.Sum(nil)
	sha1String := hex.EncodeToString(hashed)

	claims := UserClaims{
		RegisteredClaims: jwt.RegisteredClaims{
			ExpiresAt: jwt.NewNumericDate(time.Now().Add(j.rtExpiration)),
		},
		Iden: sha1String,
	}
	token := jwt.NewWithClaims(jwt.SigningMethodHS512, claims)

	tokenStr, err := token.SignedString([]byte(viper.GetString("jwt.admin")))
	if err != nil {
		return "", err
	}
	adminFields := map[string]interface{}{
		"admin_id":       admin.AdminID,
		"email":          admin.Email,
		"mobile":         admin.Mobile,
		"head_sculpture": admin.HeadSculpture,
		"login_name":     admin.LoginName,
		"admin_name":     admin.AdminName,
		"user_type":      admin.UserType,
	}

	//TODO  没有添加过期日期
	err = j.cmd.HMSet(ctx, "admin:login:"+sha1String, adminFields).Err()

	if err != nil {
		log.Fatalln(err)
		return "", err
	}

	//ctx.Header("x-jwt-token", tokenStr)
	return tokenStr, nil
}

func (j *jwtHandler) ClearToken(ctx *gin.Context, adminId int64) error {
	sha1Hash := sha1.New()
	idBytes := []byte(fmt.Sprintf("%d", adminId))
	sha1Hash.Write(idBytes)
	hashed := sha1Hash.Sum(nil)
	sha1String := hex.EncodeToString(hashed)
	return j.cmd.Del(ctx, "admin:login:"+sha1String).Err()
}
